package common.display
{
    import asset.global.ErrorImageAsset;
    
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.geom.Rectangle;
    import flash.system.ApplicationDomain;
    import flash.system.LoaderContext;
    import flash.system.SecurityDomain;
    
    import kernel.cdn.CDN;
    import kernel.core.Core;
    
    import org.granite.net.DisplayAssetLoader;
    import org.granite.net.ILoader;
    import org.granite.net.ILoaderQueueHandler;
    import org.granite.net.LoaderConfiguration;
    import org.granite.net.LoaderQueue;

    [Event(name = "complete" , type = "flash.events.Event")]

    public class URLSwf extends EmptyPane implements ILoaderQueueHandler
    {
        private static var _instanceIDAccumulator:uint;

        private static var _queue:LoaderQueue = new LoaderQueue (3 , 40);

        private static const TEST_LAYER:Sprite = new Sprite ();
        private var _isError:Boolean;
        private var _isDestroyed:Boolean;
        private var _isLoad:Boolean;
        private var _showError:Boolean;
        private var _showLoading:Boolean;
        private var _offsetX:int;
        private var _offsetY:int;
        private var _swfHeight:int;
        private var _swfWidth:int;
        private var _loading:LoadingMovie;
        private var _mc:MovieClip;
        private var _loadingLayer:Sprite;
        private var _instanceID:String;
        private var _url:String;
        private var _myLoaders:Array = [];

        private var _ignore:Boolean = false;

        public function URLSwf(url:String = null , showLoading:Boolean = true , showError:Boolean = true)
        {
            this.mouseEnabled = false;
            this.mouseChildren = false;
            _isLoad = false;
            _showLoading = showLoading;
            _showError = showError;
            _instanceID = (_instanceIDAccumulator++).toString ();
            if (url != null)
                this.load (url);
        }

        public function disposeMemery():void
        {
            if (_mc)
            {
                while (_mc.numChildren > 0)
                {
                    _mc.removeChildAt (0);
                }
                if (_mc.parent)
                {
                    _mc.parent.removeChild (_mc);
                }
            }
            var ldr:DisplayAssetLoader;
            for (var i:int = 0 ; i < _myLoaders.length ; i++)
            {
                ldr = _myLoaders[i] as DisplayAssetLoader;
                if (ldr)
                {
                    ldr.close ();
                    trace ("DisplayAssetLoader close");
                }
            }
            _myLoaders = [];
        }



        public function set ignore(value:Boolean):void
        {
            _ignore = value;
            maskEnabled = !value;
        }

        public function get isLoadOk():Boolean
        {
            return _mc != null;
        }

        public function get offsetX():int
        {
            return _offsetX;
        }

        public function get offsetY():int
        {
            return _offsetY;
        }

        public function get swfHeight():int
        {
            return _swfHeight;
        }

        public function get swfWidth():int
        {
            return _swfWidth;
        }

        public function get instanceID():String
        {
            return _instanceID;
        }

        public function get movieClip():MovieClip
        {
            return _mc;
        }

        public function createLoaderConfiguration(path:String):LoaderConfiguration
        {
            var lconfig:LoaderConfiguration = new LoaderConfiguration ();
            lconfig.loader = new DisplayAssetLoader ();
            _myLoaders.push (lconfig.loader);
            lconfig.request = CDN.creatNewURLRequest (path);
            lconfig.context = loaderContext;
            return lconfig;
        }

        private function get loaderContext():LoaderContext
        {
            return new LoaderContext (false , ApplicationDomain.currentDomain , Core.isLocal ? null : SecurityDomain.currentDomain);
        }

        public function loadedResult(path:String , loader:ILoader , error:Boolean):void
        {
            _removeLoading ();

            if (error)
            {
                _mc = new MovieClip ();
                var img:BitmapData = new ErrorImageAsset ();
                _mc.addChild (new Bitmap (img));
                if (_mc != null)
                {
                    _swfWidth = _mc.width;
                    _swfHeight = _mc.height;
                }
            }
            else
            {
                _mc = loader.data as MovieClip;
                if (_mc != null)
                {
                    _swfWidth = _mc.width;
                    _swfHeight = _mc.height;
                    if (!_ignore)
                    {
                        TEST_LAYER.addChild (_mc);
                        var rect:Rectangle = TEST_LAYER.getBounds (_mc);
                        TEST_LAYER.removeChild (_mc);
                        _offsetX = rect.x;
                        _offsetY = rect.y;
                    }
                }
            }

            _substanceLayer.addChild (_mc);
            _isError = error;
            update ();
            this.dispatchEvent (new Event (Event.COMPLETE));
        }

        public function get url():String
        {
            return _url;
        }

        public function play():void
        {
            if (_mc != null)
            {
                _mc.play ();
            }
        }

        public function stop():void
        {
            if (_mc != null)
            {
                _mc.stop ();
            }
        }

        public function destroy():void
        {
            if (_isLoad && !_isDestroyed)
            {
                this.removeEventListener (Event.ADDED_TO_STAGE , _addedToStageHandler);
                _removeLoading ();
                if (_mc != null)
                {
                    if (_mc.parent != null)
                        _mc.parent.removeChild (_mc);
                    _mc.stop ();
                    _mc = null;
                }

                _queue.remove (_url , this);

                this.removeEventListener (Event.RESIZE , _resizeHandler);
                _mc = null;
            }
        }

        public function load(url:String):void
        {
            if (_isLoad || _isDestroyed)
            {
                throw new Error ('fuck');
            }
            else
            {
                this.addEventListener (Event.RESIZE , _resizeHandler , false , 0 , true);
                _url = url;
                if (_showLoading)
                {
                    if (this.stage == null)
                    {
                        this.addEventListener (Event.ADDED_TO_STAGE , _addedToStageHandler , false , 0 , true);
                    }
                    else
                    {
                        _addedToStageHandler (null);
                    }
                }

                _queue.add (_url , this);

                _isLoad = true;
            }
        }

        protected function _draw():void
        {
            if (_mc != null)
            {
                if (_mc.parent != _substanceLayer)
                    _substanceLayer.addChild (_mc);
            }
            _drawSource ();
        }

        protected function _drawSource():void
        {
            if (_mc != null)
            {
                if (_isError && !_showError)
                    return;
                var w:Number;
                var h:Number;
                var iw:int = _mc.width;
                var ih:int = _mc.height;
                if (iw > _width || ih > _height)
                {
                    var kw:Number = _width / iw;
                    var kh:Number = _height / ih;
                    var min:Number = kw > kh ? kh : kw;
                    w = iw * min;
                    h = ih * min;
                }
                else
                {
                    w = iw;
                    h = ih;
                }
                _mc.scaleX = 1;
                _mc.scaleY = 1;
                if (!_ignore)
                {
                    _mc.width = w;
                    _mc.height = h;
                    var sx:Number = iw == 0 ? 0 : w / iw;
                    var sy:Number = ih == 0 ? 0 : h / ih;
                    _mc.x = int ((_width - w) / 2) - _offsetX * sx;
                    _mc.y = int ((_height - h) / 2) - _offsetY * sy;
                }
                else
                {
                    _mc.x = 0;
                    _mc.y = 0;
                }
            }
        }

        protected override function _redraw():void
        {
            super._redraw ();
            _draw ();
        }

        private function _removeLoading():void
        {
            this.removeEventListener (Event.ADDED_TO_STAGE , _addedToStageHandler);
            if (_loadingLayer != null)
            {
                this.removeEventListener (Event.ADDED_TO_STAGE , _addedToStageHandler2);
                this.removeEventListener (Event.REMOVED_FROM_STAGE , _removedFromStageHandler);
                _substanceLayer.removeChild (_loadingLayer);
                _loading.stop ();
                _loadingLayer.removeChild (_loading);
                _loadingLayer = null;
                _loading = null;
            }
        }

        private function _setLoadingSize():void
        {
            if (_loadingLayer != null && _loading != null)
            {
                if (_width == 0 || _height == 0)
                {
                    _loadingLayer.width = 0;
                    _loadingLayer.height = 0;
                }
                else
                {
                    if (_loading.width > _width || _loading.height > _height)
                    {
                        var kw:Number = _width / _loading.width;
                        var kh:Number = _height / _loading.height;
                        var min:Number = kw > kh ? kh : kw;
                        _loadingLayer.scaleX = min;
                        _loadingLayer.scaleY = min;
                    }
                    _loadingLayer.x = _width / 2;
                    _loadingLayer.y = _height / 2;
                }
            }
        }

        //handlers
        private function _addedToStageHandler(e:Event):void
        {
            this.removeEventListener (Event.ADDED_TO_STAGE , _addedToStageHandler);
            _loadingLayer = new Sprite ();
            _loadingLayer.mouseEnabled = false;
            _loadingLayer.mouseChildren = false;
            _loading = new LoadingMovie ();
            _loadingLayer.addChild (_loading);
            _substanceLayer.addChild (_loadingLayer);
            _setLoadingSize ();
            this.addEventListener (Event.ADDED_TO_STAGE , _addedToStageHandler2 , false , 0 , true);
            this.addEventListener (Event.REMOVED_FROM_STAGE , _removedFromStageHandler , false , 0 , true);
        }

        private function _addedToStageHandler2(e:Event):void
        {
            _loading.play ();
        }

        private function _removedFromStageHandler(e:Event):void
        {
            _loading.stop ();
        }

        private function _resizeHandler(e:Event):void
        {
            if (_mc != null)
            {
                update ();
            }
            _setLoadingSize ();
        }
    }
}
